using Admin.NET.Core.Service;
using Furion.DatabaseAccessor;
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using System.ComponentModel;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.Extensions.Configuration;
using Admin.NET.Application.Entity;
using System.Collections.Concurrent;

namespace Admin.NET.Application.Service.KnowledgeBase;

/// <summary>
/// RAGflow知识同步服务
/// 从RAGflow获取解析后的知识并同步到向量数据库
/// </summary>
[ApiDescriptionSettings(Name = "ragFlowSync", Order = 381)]
public class RAGFlowSyncService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<Admin.NET.Application.Entity.KnowledgeBase> _knowledgeRepo;
    private readonly SqlSugarRepository<Admin.NET.Application.Entity.KnowledgeVector> _vectorRepo;
    private readonly KnowledgeBaseService _knowledgeBaseService;
    private readonly HttpClient _httpClient;
    private readonly IConfiguration _configuration;

    public RAGFlowSyncService(
        SqlSugarRepository<Admin.NET.Application.Entity.KnowledgeBase> knowledgeRepo,
        SqlSugarRepository<Admin.NET.Application.Entity.KnowledgeVector> vectorRepo,
        KnowledgeBaseService knowledgeBaseService,
        HttpClient httpClient,
        IConfiguration configuration)
    {
        _knowledgeRepo = knowledgeRepo;
        _vectorRepo = vectorRepo;
        _knowledgeBaseService = knowledgeBaseService;
        _httpClient = httpClient;
        _configuration = configuration;

        // 扩大HTTP超时，避免大数据集同步时超时（默认50s过短）
        if (_httpClient.Timeout < TimeSpan.FromSeconds(180))
        {
            _httpClient.Timeout = TimeSpan.FromSeconds(180);
        }
    }

    /// <summary>
    /// 统一的HTTP发送（带重试与退避）
    /// </summary>
    private async Task<HttpResponseMessage> SendWithRetryAsync(Func<HttpRequestMessage> requestFactory, int maxRetries = 2)
    {
        var delay = TimeSpan.FromSeconds(2);

        for (int attempt = 0; ; attempt++)
        {
            using var req = requestFactory();
            try
            {
                var resp = await _httpClient.SendAsync(req);
                // 对 5xx 做重试
                if ((int)resp.StatusCode >= 500 && attempt < maxRetries)
                {
                    await Task.Delay(delay);
                    delay = TimeSpan.FromSeconds(delay.TotalSeconds * 2);
                    continue;
                }
                return resp;
            }
            catch (TaskCanceledException) when (attempt < maxRetries)
            {
                // 超时重试
                await Task.Delay(delay);
                delay = TimeSpan.FromSeconds(delay.TotalSeconds * 2);
                continue;
            }
        }
    }

    /// <summary>
    /// 获取RAGflow知识库列表
    /// </summary>
    [DisplayName("获取RAGflow知识库列表")]
    [ApiDescriptionSettings(Name = "GetRAGFlowKnowledgeBases"), HttpGet]
    public async Task<List<RAGFlowKnowledgeBase>> GetRAGFlowKnowledgeBases()
    {
        try
        {
            var ragFlowUrl = _configuration["RAGSettings:RAGFlowUrl"] ?? "http://localhost:8080";
            var apiKey = _configuration["RAGSettings:RAGFlowApiKey"] ?? "";
            
            Console.WriteLine($"获取RAGflow知识库列表 - URL: {ragFlowUrl}, API Key: {(string.IsNullOrEmpty(apiKey) ? "未配置" : "已配置")}");
            
            var result = await GetKnowledgeBasesAsync(ragFlowUrl, apiKey);
            
            if (result.Count == 0)
            {
                Console.WriteLine("警告: 未获取到任何知识库，请检查:");
                Console.WriteLine($"  1. RAGflow服务是否运行: {ragFlowUrl}");
                Console.WriteLine($"  2. API Key是否正确配置");
                Console.WriteLine($"  3. RAGflow API端点是否正确");
            }
            
            return result;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"获取RAGflow知识库列表异常: {ex.Message}");
            Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
            return new List<RAGFlowKnowledgeBase>();
        }
    }

    /// <summary>
    /// 同步RAGflow知识库到向量数据库
    /// </summary>
    [DisplayName("同步RAGflow知识库")]
    [ApiDescriptionSettings(Name = "SyncFromRAGFlow"), HttpPost]
    public async Task<SyncResult> SyncFromRAGFlow([FromBody] SyncRAGFlowInput input)
    {
        var result = new SyncResult
        {
            Total = 0,
            Success = 0,
            Failed = 0,
            Errors = new List<string>()
        };

        try
        {
            var ragFlowUrl = _configuration["RAGSettings:RAGFlowUrl"] ?? "http://localhost:8080";
            var apiKey = _configuration["RAGSettings:RAGFlowApiKey"] ?? "";

            var kbId = input?.KbId;
            
            // 如果没有指定知识库ID，获取所有知识库
            if (string.IsNullOrEmpty(kbId))
            {
                var kbList = await GetKnowledgeBasesAsync(ragFlowUrl, apiKey);
                foreach (var kb in kbList)
                {
                    var kbResult = await SyncKnowledgeBaseAsync(kb.Id, ragFlowUrl, apiKey);
                    result.Total += kbResult.Total;
                    result.Success += kbResult.Success;
                    result.Failed += kbResult.Failed;
                    result.Errors.AddRange(kbResult.Errors);
                }
            }
            else
            {
                var kbResult = await SyncKnowledgeBaseAsync(kbId, ragFlowUrl, apiKey);
                result = kbResult;
            }
        }
        catch (Exception ex)
        {
            result.Errors.Add($"同步失败: {ex.Message}");
        }

        return result;
    }

    /// <summary>
    /// 获取RAGflow知识库列表
    /// </summary>
    private async Task<List<RAGFlowKnowledgeBase>> GetKnowledgeBasesAsync(string ragFlowUrl, string apiKey)
    {
        // 尝试多个可能的API端点（按照RAGFlow API文档，应该优先使用datasets复数形式）
        var possibleEndpoints = new[]
        {
            "/api/v1/datasets",     // RAGFlow API文档标准端点（复数形式）
            "/api/v1/dataset",      // RAGflow常用端点（单数形式）
            "/api/v1/kb",           // 知识库端点
            "/api/v1/knowledgebase" // 完整名称
        };

        foreach (var endpoint in possibleEndpoints)
        {
            try
            {
                var url = $"{ragFlowUrl}{endpoint}";
                Console.WriteLine($"尝试获取知识库列表: {url}");
                
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                if (!string.IsNullOrEmpty(apiKey))
                {
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
                }

                var response = await SendWithRetryAsync(() => new HttpRequestMessage(HttpMethod.Get, url)
                {
                    Headers = { Authorization = request.Headers.Authorization }
                });
                
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"API响应内容: {content}");
                    
                    // 尝试不同的响应格式
                    try
                    {
                        // 格式1: { code: 200, data: [...] }
                        var result = JsonSerializer.Deserialize<RAGFlowResponse<RAGFlowKnowledgeBase[]>>(content);
                        if (result?.Data != null && result.Data.Length > 0)
                        {
                            Console.WriteLine($"成功获取 {result.Data.Length} 个知识库 (端点: {endpoint})");
                            // 打印第一个知识库的详细信息用于调试
                            if (result.Data.Length > 0)
                            {
                                var firstKb = result.Data[0];
                                Console.WriteLine($"第一个知识库详情 - Id: {firstKb.Id}, Name: {firstKb.Name}, DatasetId: {firstKb.DatasetId}, KbId: {firstKb.KbId}, UnderscoreId: {firstKb.UnderscoreId}");
                            }
                            return NormalizeKnowledgeBases(result.Data.ToList());
                        }
                    }
                    catch
                    {
                        // 格式2: 直接是数组
                        try
                        {
                            var arrayResult = JsonSerializer.Deserialize<RAGFlowKnowledgeBase[]>(content);
                            if (arrayResult != null && arrayResult.Length > 0)
                            {
                                Console.WriteLine($"成功获取 {arrayResult.Length} 个知识库 (端点: {endpoint})");
                                return NormalizeKnowledgeBases(arrayResult.ToList());
                            }
                        }
                        catch (Exception ex2)
                        {
                            Console.WriteLine($"解析响应格式2失败: {ex2.Message}");
                        }
                    }

                    // 格式3: { data: [...] } (无code字段)
                    try
                    {
                        using var doc = JsonDocument.Parse(content);
                        if (doc.RootElement.TryGetProperty("data", out var dataElement))
                        {
                            var items = JsonSerializer.Deserialize<RAGFlowKnowledgeBase[]>(dataElement.GetRawText());
                            if (items != null && items.Length > 0)
                            {
                                Console.WriteLine($"成功获取 {items.Length} 个知识库 (端点: {endpoint})");
                                return NormalizeKnowledgeBases(items.ToList());
                            }
                        }
                    }
                    catch (Exception ex3)
                    {
                        Console.WriteLine($"解析响应格式3失败: {ex3.Message}");
                    }
                }
                else
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"端点 {endpoint} 返回 {response.StatusCode}: {errorContent}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"尝试端点 {endpoint} 失败: {ex.Message}");
                // 继续尝试下一个端点
            }
        }

        Console.WriteLine("所有端点尝试失败，返回空列表");
        return new List<RAGFlowKnowledgeBase>();
    }

    /// <summary>
    /// 规范化知识库对象，确保Id和Name字段正确映射
    /// </summary>
    private List<RAGFlowKnowledgeBase> NormalizeKnowledgeBases(List<RAGFlowKnowledgeBase> kbList)
    {
        foreach (var kb in kbList)
        {
            // 优先使用DatasetId作为真正的ID（用于API调用）
            // 如果DatasetId不为空，将其设为Id
            if (!string.IsNullOrEmpty(kb.DatasetId))
            {
                // DatasetId是真正的dataset ID，优先使用
                if (string.IsNullOrEmpty(kb.Id) || kb.Id != kb.DatasetId)
                {
                    Console.WriteLine($"知识库 {kb.Name} 使用dataset_id: {kb.DatasetId} (原id: {kb.Id ?? "空"})");
                    kb.Id = kb.DatasetId;
                }
            }
            else if (string.IsNullOrEmpty(kb.Id))
            {
                // 如果Id为空，尝试使用其他字段
                kb.Id = kb.UnderscoreId ?? kb.KbId ?? "";
                Console.WriteLine($"知识库 {kb.Name} 使用备用ID字段: {kb.Id}");
            }
            
            // 如果Name为空，尝试使用Title
            if (string.IsNullOrEmpty(kb.Name))
            {
                kb.Name = kb.Title ?? "未命名知识库";
            }
            
            // 如果没有Description，使用空字符串
            if (kb.Description == null)
            {
                kb.Description = "";
            }
            
            Console.WriteLine($"规范化后的知识库: Id={kb.Id}, Name={kb.Name}, DatasetId={kb.DatasetId}, KbId={kb.KbId}");
        }
        
        return kbList;
    }

    /// <summary>
    /// 同步指定知识库的所有chunks
    /// </summary>
    private async Task<SyncResult> SyncKnowledgeBaseAsync(string kbId, string ragFlowUrl, string apiKey)
    {
        var result = new SyncResult
        {
            Total = 0,
            Success = 0,
            Failed = 0,
            Errors = new List<string>()
        };

        try
        {
            Console.WriteLine($"=== 开始同步知识库: {kbId} ===");
            Console.WriteLine($"RAGFlow URL: {ragFlowUrl}");
            Console.WriteLine($"API Key: {(string.IsNullOrEmpty(apiKey) ? "未配置" : "已配置")}");
            
            // 获取知识库的所有chunks
            var chunks = await GetChunksFromRAGFlowAsync(kbId, ragFlowUrl, apiKey);
            result.Total = chunks.Count;

            Console.WriteLine($"找到 {chunks.Count} 个知识块，开始同步...");

            foreach (var chunk in chunks)
            {
                try
                {
                    // 检查是否已存在（通过source和document_id判断）
                    var existing = await _knowledgeRepo.GetFirstAsync(k =>
                        k.Source == $"RAGFlow-{kbId}" &&
                        k.DocumentUrl != null &&
                        k.DocumentUrl.Contains($"chunk-{chunk.Id}"));

                    if (existing != null)
                    {
                        // 更新现有知识
                        var content = chunk.GetContent() ?? string.Empty;
                        existing.Title = chunk.Title ?? $"知识块-{chunk.Id}";
                        existing.Content = content;
                        existing.LastUpdated = DateTime.Now;
                        await _knowledgeRepo.UpdateAsync(existing);

                        // 更新向量（通过更新知识来触发向量更新）
                        await _knowledgeBaseService.Update(existing);
                        
                        // 验证向量是否成功存储到Qdrant
                        await Task.Delay(500); // 等待一下确保操作完成
                        var vectorExists = await _knowledgeBaseService.CheckVectorExistsInQdrantAsync(existing.Id);
                        if (vectorExists)
                        {
                            result.Success++;
                        }
                        else
                        {
                            result.Failed++;
                            result.Errors.Add($"知识块 {chunk.Id} 更新成功，但向量未成功存储到Qdrant");
                            Console.WriteLine($"警告: 知识 {existing.Title} 已更新，但向量未成功存储到Qdrant");
                        }
                    }
                    else
                    {
                        // 创建新知识
                        var content = chunk.GetContent() ?? string.Empty;
                        var knowledge = new Admin.NET.Application.Entity.KnowledgeBase
                        {
                            Title = chunk.Title ?? $"知识块-{chunk.Id}",
                            Content = content,
                            Category = "ragflow_import",
                            Keywords = ExtractKeywords(content),
                            DocumentType = "text",
                            Source = $"RAGFlow-{kbId}",
                            DocumentUrl = $"{kbId}/chunk-{chunk.Id}",
                            Priority = 1,
                            IsEnabled = true,
                            LastUpdated = DateTime.Now
                        };

                        var id = await _knowledgeBaseService.Add(knowledge);

                        // 验证向量是否成功存储到Qdrant
                        await Task.Delay(500); // 等待一下确保操作完成
                        var vectorExists = await _knowledgeBaseService.CheckVectorExistsInQdrantAsync(id);
                        if (vectorExists)
                        {
                            result.Success++;
                        }
                        else
                        {
                            result.Failed++;
                            result.Errors.Add($"知识块 {chunk.Id} 已创建，但向量未成功存储到Qdrant");
                            Console.WriteLine($"警告: 知识 {knowledge.Title} 已创建，但向量未成功存储到Qdrant");
                        }
                    }
                }
                catch (Exception ex)
                {
                    result.Failed++;
                    result.Errors.Add($"同步知识块 {chunk.Id} 失败: {ex.Message}");
                    Console.WriteLine($"同步知识块失败: {ex.Message}");
                }
            }
        }
        catch (Exception ex)
        {
            result.Errors.Add($"同步知识库 {kbId} 失败: {ex.Message}");
            Console.WriteLine($"同步知识库失败: {ex.Message}");
        }

        return result;
    }

    /// <summary>
    /// 从RAGflow获取chunks
    /// </summary>
    private async Task<List<RAGFlowChunk>> GetChunksFromRAGFlowAsync(string kbId, string ragFlowUrl, string apiKey)
    {
        Console.WriteLine($"开始获取知识库 {kbId} 的chunks...");
        
        // 首先尝试获取知识库详情，看是否有真正的dataset_id
        string actualDatasetId = await GetActualDatasetIdAsync(kbId, ragFlowUrl, apiKey);
        if (!string.IsNullOrEmpty(actualDatasetId) && actualDatasetId != kbId)
        {
            Console.WriteLine($"通过知识库详情获取到dataset_id: {actualDatasetId}，将使用此ID获取chunks");
            kbId = actualDatasetId;
        }
        
        // 直接通过文档列表获取，减少404/405日志
        Console.WriteLine("跳过数据集chunks探测，改为通过文档获取chunks...");
        return await GetChunksViaDocumentsAsync(kbId, ragFlowUrl, apiKey);
    }

    /// <summary>
    /// 通过文档列表获取chunks（备用方法）
    /// </summary>
    private async Task<List<RAGFlowChunk>> GetChunksViaDocumentsAsync(string kbId, string ragFlowUrl, string apiKey)
    {
        var allChunks = new List<RAGFlowChunk>();

        // 仅保留标准端点
        var possibleDocEndpoints = new[]
        {
            $"/api/v1/datasets/{kbId}/documents",
        };

        foreach (var docEndpoint in possibleDocEndpoints)
        {
            try
            {
                var docUrl = $"{ragFlowUrl}{docEndpoint}";
                Console.WriteLine($"尝试获取文档列表: {docUrl}");
                
                var docRequest = new HttpRequestMessage(HttpMethod.Get, docUrl);
                if (!string.IsNullOrEmpty(apiKey))
                {
                    docRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
                }

                var docResponse = await SendWithRetryAsync(() => new HttpRequestMessage(HttpMethod.Get, docUrl)
                {
                    Headers = { Authorization = docRequest.Headers.Authorization }
                });
                if (docResponse.IsSuccessStatusCode)
                {
                    var docContent = await docResponse.Content.ReadAsStringAsync();
                    Console.WriteLine($"文档列表响应: {docContent.Substring(0, Math.Min(500, docContent.Length))}...");
                    
                    // 尝试多种解析格式
                    RAGFlowDocument[] documents = null;
                    
                    try
                    {
                        // 首先尝试解析RAGFlow标准格式：{"code": 0, "data": {"docs": [...]}}
                        using var doc = JsonDocument.Parse(docContent);
                        
                        // 检查是否有code字段（RAGFlow返回code=0表示成功）
                        if (doc.RootElement.TryGetProperty("code", out var codeElement))
                        {
                            var code = codeElement.GetInt32();
                            Console.WriteLine($"响应code: {code}");
                            
                            // 检查是否有data字段
                            if (doc.RootElement.TryGetProperty("data", out var dataElement))
                            {
                                // 检查data是否是对象，且包含docs属性
                                if (dataElement.ValueKind == JsonValueKind.Object && dataElement.TryGetProperty("docs", out var docsElement))
                                {
                                    Console.WriteLine($"检测到嵌套结构 data.docs，尝试解析...");
                                    documents = JsonSerializer.Deserialize<RAGFlowDocument[]>(docsElement.GetRawText());
                                    if (documents != null && documents.Length > 0)
                                    {
                                        Console.WriteLine($"成功从data.docs解析到 {documents.Length} 个文档");
                                    }
                                }
                                // 如果data直接是数组
                                else if (dataElement.ValueKind == JsonValueKind.Array)
                                {
                                    Console.WriteLine($"检测到data是数组格式，尝试解析...");
                                    documents = JsonSerializer.Deserialize<RAGFlowDocument[]>(dataElement.GetRawText());
                                    if (documents != null && documents.Length > 0)
                                    {
                                        Console.WriteLine($"成功从data数组解析到 {documents.Length} 个文档");
                                    }
                                }
                            }
                        }
                        
                        // 如果上面都没成功，尝试标准响应格式 RAGFlowResponse
                        if (documents == null || documents.Length == 0)
                        {
                            var docResult = JsonSerializer.Deserialize<RAGFlowResponse<RAGFlowDocument[]>>(docContent);
                            documents = docResult?.Data;
                            if (documents != null && documents.Length > 0)
                            {
                                Console.WriteLine($"成功从RAGFlowResponse解析到 {documents.Length} 个文档");
                            }
                        }
                        
                        // 如果还是没成功，尝试直接解析为数组
                        if (documents == null || documents.Length == 0)
                        {
                            documents = JsonSerializer.Deserialize<RAGFlowDocument[]>(docContent);
                            if (documents != null && documents.Length > 0)
                            {
                                Console.WriteLine($"成功直接解析为数组，获取到 {documents.Length} 个文档");
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"解析文档列表时发生异常: {ex.Message}");
                        Console.WriteLine($"响应内容: {docContent.Substring(0, Math.Min(1000, docContent.Length))}");
                    }

                    if (documents != null && documents.Length > 0)
                    {
                        Console.WriteLine($"成功获取 {documents.Length} 个文档，开始并发获取chunks...");

                        var bag = new ConcurrentBag<RAGFlowChunk>();
                        var semaphore = new SemaphoreSlim(6);
                        var tasks = new List<Task>();

                        foreach (var doc in documents)
                        {
                            await semaphore.WaitAsync();
                            tasks.Add(Task.Run(async () =>
                            {
                                try
                                {
                                    var chunkUrl = $"{ragFlowUrl}/api/v1/datasets/{kbId}/documents/{doc.Id}/chunks";
                                    var chunkRequest = new HttpRequestMessage(HttpMethod.Get, chunkUrl);
                                    if (!string.IsNullOrEmpty(apiKey))
                                    {
                                        chunkRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
                                    }

                                    var chunkResponse = await SendWithRetryAsync(() => new HttpRequestMessage(HttpMethod.Get, chunkUrl)
                                    {
                                        Headers = { Authorization = chunkRequest.Headers.Authorization }
                                    });

                                    if (!chunkResponse.IsSuccessStatusCode) return;

                                    var chunkContent = await chunkResponse.Content.ReadAsStringAsync();
                                    RAGFlowChunk[] chunks = null;
                                    try
                                    {
                                        using var chunkDoc = JsonDocument.Parse(chunkContent);
                                        if (chunkDoc.RootElement.TryGetProperty("data", out var dataElement))
                                        {
                                            if (dataElement.ValueKind == JsonValueKind.Object && dataElement.TryGetProperty("chunks", out var chunksElement))
                                            {
                                                chunks = JsonSerializer.Deserialize<RAGFlowChunk[]>(chunksElement.GetRawText());
                                            }
                                            else if (dataElement.ValueKind == JsonValueKind.Array)
                                            {
                                                chunks = JsonSerializer.Deserialize<RAGFlowChunk[]>(dataElement.GetRawText());
                                            }
                                        }
                                        if (chunks == null)
                                        {
                                            var chunkResult = JsonSerializer.Deserialize<RAGFlowResponse<RAGFlowChunk[]>>(chunkContent);
                                            chunks = chunkResult?.Data ?? JsonSerializer.Deserialize<RAGFlowChunk[]>(chunkContent);
                                        }
                                    }
                                    catch { }

                                    if (chunks != null && chunks.Length > 0)
                                    {
                                        foreach (var c in chunks)
                                        {
                                            c.Title = doc.Name;
                                            bag.Add(c);
                                        }
                                    }
                                }
                                finally
                                {
                                    semaphore.Release();
                                }
                            }));
                        }

                        await Task.WhenAll(tasks);

                        if (!bag.IsEmpty)
                        {
                            allChunks.AddRange(bag);
                            Console.WriteLine($"并发获取完成，共获取到 {allChunks.Count} 个chunks");
                            return allChunks;
                        }
                    }
                    else
                    {
                        Console.WriteLine("文档列表为空或解析失败");
                    }
                }
                else
                {
                    var errorContent = await docResponse.Content.ReadAsStringAsync();
                    Console.WriteLine($"获取文档列表失败 ({docEndpoint}): {docResponse.StatusCode} - {errorContent}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"尝试文档端点 {docEndpoint} 失败: {ex.Message}");
            }
        }

        Console.WriteLine($"所有方法尝试完毕，共获取 {allChunks.Count} 个chunks");
        return allChunks;
    }

    /// <summary>
    /// 获取实际的dataset ID（通过知识库详情API）
    /// </summary>
    private async Task<string> GetActualDatasetIdAsync(string kbId, string ragFlowUrl, string apiKey)
    {
        // 尝试多个可能的详情端点（按照RAGFlow API文档，应该优先使用datasets复数形式）
        var possibleDetailEndpoints = new[]
        {
            $"/api/v1/datasets/{kbId}",          // RAGFlow API标准端点（复数形式）
            $"/api/v1/dataset/{kbId}",           // 单数形式
            $"/api/v1/kb/{kbId}",                // KB端点
            $"/api/v1/knowledgebase/{kbId}",     // 完整名称
        };

        foreach (var endpoint in possibleDetailEndpoints)
        {
            try
            {
                var url = $"{ragFlowUrl}{endpoint}";
                Console.WriteLine($"尝试获取知识库详情: {url}");
                
                var request = new HttpRequestMessage(HttpMethod.Get, url);
                if (!string.IsNullOrEmpty(apiKey))
                {
                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
                }

                var response = await SendWithRetryAsync(() => new HttpRequestMessage(HttpMethod.Get, url)
                {
                    Headers = { Authorization = request.Headers.Authorization }
                });
                
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"知识库详情响应: {content.Substring(0, Math.Min(500, content.Length))}...");
                    
                    // 尝试解析获取dataset_id
                    try
                    {
                        using var doc = JsonDocument.Parse(content);
                        
                        // 尝试从data字段获取
                        if (doc.RootElement.TryGetProperty("data", out var dataElement))
                        {
                            // 查找dataset_id字段
                            if (dataElement.TryGetProperty("dataset_id", out var datasetIdElement))
                            {
                                var datasetId = datasetIdElement.GetString();
                                if (!string.IsNullOrEmpty(datasetId))
                                {
                                    Console.WriteLine($"从data.dataset_id获取到: {datasetId}");
                                    return datasetId;
                                }
                            }
                            // 查找id字段（可能是dataset_id）
                            if (dataElement.TryGetProperty("id", out var idElement))
                            {
                                var id = idElement.GetString();
                                Console.WriteLine($"从data.id获取到: {id}");
                            }
                        }
                        
                        // 直接查找dataset_id
                        if (doc.RootElement.TryGetProperty("dataset_id", out var rootDatasetIdElement))
                        {
                            var datasetId = rootDatasetIdElement.GetString();
                            if (!string.IsNullOrEmpty(datasetId))
                            {
                                Console.WriteLine($"从dataset_id获取到: {datasetId}");
                                return datasetId;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"解析知识库详情失败: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"尝试获取知识库详情失败 ({endpoint}): {ex.Message}");
            }
        }
        
        Console.WriteLine("无法获取知识库详情，将使用原始ID");
        return kbId; // 返回原始ID
    }

    /// <summary>
    /// 简单关键词提取
    /// </summary>
    private string ExtractKeywords(string content)
    {
        if (string.IsNullOrEmpty(content))
            return "";

        // 简单的关键词提取：取前100个字符中的关键词
        var keywords = new List<string>();
        var words = content.Substring(0, Math.Min(100, content.Length))
            .Split(new[] { ' ', '，', '。', '、', ',', '.', ';', '；' }, StringSplitOptions.RemoveEmptyEntries)
            .Where(w => w.Length >= 2)
            .Take(10)
            .ToList();

        return string.Join(",", words);
    }

    /// <summary>
    /// 启用自动同步（定时任务）
    /// </summary>
    [DisplayName("启用RAGflow自动同步")]
    public async Task<bool> EnableAutoSync(bool enabled = true, int intervalMinutes = 60)
    {
        // 这里可以实现定时任务逻辑
        // 建议使用Hangfire或Quartz.NET等任务调度框架
        Console.WriteLine($"RAGflow自动同步已{(enabled ? "启用" : "禁用")}，间隔: {intervalMinutes}分钟");
        return enabled;
    }
}

// RAGflow响应模型
public class RAGFlowResponse<T>
{
    public int Code { get; set; }
    public string Message { get; set; }
    public T Data { get; set; }
}

// RAGflow知识库模型
public class RAGFlowKnowledgeBase
{
    [JsonPropertyName("id")]
    public string Id { get; set; }
    
    [JsonPropertyName("name")]
    public string Name { get; set; }
    
    [JsonPropertyName("description")]
    public string Description { get; set; }
    
    // RAGflow可能使用的其他字段名
    [JsonPropertyName("_id")]
    public string UnderscoreId { get; set; }
    
    [JsonPropertyName("dataset_id")]
    public string DatasetId { get; set; }
    
    [JsonPropertyName("kb_id")]
    public string KbId { get; set; }
    
    [JsonPropertyName("title")]
    public string Title { get; set; }
}

// RAGflow文档模型
public class RAGFlowDocument
{
    [JsonPropertyName("id")]
    public string Id { get; set; }
    
    [JsonPropertyName("name")]
    public string Name { get; set; }
    
    [JsonPropertyName("type")]
    public string Type { get; set; }
    
    [JsonPropertyName("dataset_id")]
    public string DatasetId { get; set; }
    
    [JsonPropertyName("location")]
    public string Location { get; set; }
    
    [JsonPropertyName("chunk_count")]
    public int? ChunkCount { get; set; }
}

// RAGflow Chunk模型
public class RAGFlowChunk
{
    [JsonPropertyName("id")]
    public string Id { get; set; }
    
    [JsonPropertyName("title")]
    public string Title { get; set; }
    
    [JsonPropertyName("content")]
    public string Content { get; set; }
    
    [JsonPropertyName("doc_id")]
    public string DocId { get; set; }
    
    [JsonPropertyName("page_num")]
    public int? PageNum { get; set; }
    
    [JsonPropertyName("document_id")]
    public string DocumentId { get; set; }
    
    [JsonPropertyName("text")]
    public string Text { get; set; }
    
    // 如果Content为空，尝试使用Text
    public string GetContent() => !string.IsNullOrEmpty(Content) ? Content : Text;
}

// 同步输入模型
public class SyncRAGFlowInput
{
    public string KbId { get; set; }
}

// 同步结果模型
public class SyncResult
{
    public int Total { get; set; }
    public int Success { get; set; }
    public int Failed { get; set; }
    public List<string> Errors { get; set; } = new();
}

